package br.com.hmm.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import br.com.hmm.entidade.Categoria;

/**
 * Classe que manipula todas as ações relacionadas à Categoria
 * @author carlos
 * 
 */
public class CategoriaDAO {

	private Connection conn = null;
	private static final String INSERT_CATEGORIA = "INSERT INTO CATEGORIA(CAT_ID,CAT_NOME,CAT_DESCRICAO) VALUES(NULL,?,?); ";
	private static final String UPDATE_CATEGORIA = "UPDATE CATEGORIA SET CAT_NOME = ? , CAT_DESCRICAO =? WHERE CAT_ID = ? ;";
	private static final String DELETE_CATEGORIA = "DELETE FROM CATEGORIA WHERE CAT_ID = ? ;";
	private static final String EXISTE_CATEGORIA = "SELECT CAT_ID, CAT_NOME FROM CATEGORIA WHERE CAT_NOME = ? ;";
	private static final String FIND_BY_ID = "SELECT CAT_ID, CAT_NOME, CAT_DESCRICAO FROM CATEGORIA WHERE CAT_ID = ?;";
	private static final String LISTA_CATEGORIAS = "SELECT CAT_ID, CAT_NOME, CAT_DESCRICAO FROM CATEGORIA ORDER BY CAT_ID ;";
	private static final String EXISTE_ITENS_CATEGORIA = "SELECT c.CAT_ID , i.CATEGORIA_CAT_ID FROM CATEGORIA c, ITENS_CATEGORIA i WHERE c.CAT_ID = ? AND c.CAT_ID = i.CATEGORIA_CAT_ID";
	/**
	 * Construtor da Classe CategoriaDAO
	 */
	public CategoriaDAO() {

	}

	/**
	 * Insere uma categoria
	 * 
	 * @param categoria
	 * @return boolean
	 */
	public boolean inserir(Categoria categoria) {
		PreparedStatement stmt = null;
		try {
			FabricaConexao.getInstancia();
			this.conn = FabricaConexao.conectar();
			stmt = conn.prepareStatement(INSERT_CATEGORIA);
			stmt.setString(1, categoria.getNome());
			stmt.setString(2, categoria.getDescricao());
			stmt.execute();
			if(stmt.getUpdateCount() > 0){
				return true;
			}

		} catch (Exception e) {
			return false;
		} finally {
			DAOUtil.close(this.conn, stmt);
		}

		return false;
	}

	/**
	 * Atualiza uma categoria
	 * 
	 * @param categoria
	 * @return boolean
	 */
	public boolean atualizar(Categoria categoria) {
		PreparedStatement stmt = null;
		try {
			FabricaConexao.getInstancia();
			this.conn = FabricaConexao.conectar();
			stmt = conn.prepareStatement(UPDATE_CATEGORIA);
			stmt.setString(1, categoria.getNome());
			stmt.setString(2, categoria.getDescricao());
			stmt.setInt(3, categoria.getId());
			if (stmt.executeUpdate() > 0) {
				return true;
			}

		} catch (SQLException exp) {
			return false;
		} finally {
			DAOUtil.close(this.conn, stmt);
		}

		return false;
	}

	/**
	 * Remove uma categoria
	 * 
	 * @param categoria
	 * @return boolean
	 */
	public boolean delete(Categoria categoria) {
		PreparedStatement stmt = null;
		try {
			if(existeItensCategoria(categoria) == true){
				return false;
			}else{
				FabricaConexao.getInstancia();
				this.conn = FabricaConexao.conectar();
				stmt = conn.prepareStatement(DELETE_CATEGORIA);
				stmt.setInt(1, categoria.getId());
				stmt.execute();
				if(stmt.getUpdateCount()> 0){
					
					return true;
				}
			}		

		} catch (SQLException exp) {
			return false;
		} finally {
			DAOUtil.close(this.conn, stmt);
		}

		return false;
	}

	/**
	 * Checa se a categoria passada por parâmetro já existe.
	 * 
	 * @param categoria
	 * @return boolean
	 */
	public boolean existeCategoria(Categoria categoria) {
		PreparedStatement stmt = null;
		try {
			FabricaConexao.getInstancia();
			this.conn = FabricaConexao.conectar();
			stmt = conn.prepareStatement(EXISTE_CATEGORIA);
			stmt.setString(1, categoria.getNome());
			stmt.execute();
			if(stmt.getResultSet().first() == true){
				return true;
			}
		} catch (SQLException exp) {
			return false;
		} finally {
			DAOUtil.close(this.conn, stmt);
		}
		return false;
	}

	/**
	 * Encontra uma categoria pelo nome
	 * @param id
	 * @return Categoria
	 */
	public Categoria findById(int id) {
		PreparedStatement stmt = null;
		ResultSet rs = null;
		try {
			FabricaConexao.getInstancia();
			this.conn = FabricaConexao.conectar();
			stmt = conn.prepareStatement(FIND_BY_ID);
			stmt.setInt(1, id);
			rs = stmt.executeQuery();
			if (rs.first() == true) {
				Categoria c = new Categoria();
				c.setId(rs.getInt("CAT_ID"));
				c.setNome(rs.getString("CAT_NOME"));
				c.setDescricao(rs.getString("CAT_DESCRICAO"));
				return c;
			}

		} catch (SQLException exp) {
			return null;
		} finally {
			DAOUtil.close(this.conn, stmt, rs);
		}

		return null;
	}

	/**
	 * Lista todas categorias existentes
	 * @param categoria
	 * @return List<Categoria>
	 */
	public List<Categoria> list() {
		PreparedStatement stmt = null;
		ResultSet rs = null;
		List<Categoria> categorias = new ArrayList<Categoria>();
		try {
			FabricaConexao.getInstancia();
			this.conn = FabricaConexao.conectar();
			stmt = conn.prepareStatement(LISTA_CATEGORIAS);
			rs = stmt.executeQuery();
			while (rs.next()) {
				Categoria c = new Categoria();
				c.setId(rs.getInt("CAT_ID"));
				c.setNome(rs.getString("CAT_NOME"));
				c.setDescricao(rs.getString("CAT_DESCRICAO"));
				categorias.add(c);
			}
			if(!categorias.isEmpty()){
				return categorias;
			}
			
		} catch (SQLException exp) {
			return null;
		} finally {
			DAOUtil.close(this.conn, stmt, rs);
		}
		
		return null;
	}
	
	/**
	 * 
	 * @param categoria
	 * @return
	 */
	public boolean existeItensCategoria(Categoria categoria){
		PreparedStatement stmt = null;
		try {
			FabricaConexao.getInstancia();
			this.conn = FabricaConexao.conectar();
			stmt = conn.prepareStatement(EXISTE_ITENS_CATEGORIA);
			stmt.setInt(1, categoria.getId());
			stmt.execute();
			if(stmt.getResultSet().first() == true){
				return true;
			}
		} catch (SQLException exp) {
			return false;
		} finally {
			DAOUtil.close(this.conn, stmt);
		}
		return false;
	}

}
